# 个人中心
from flask import g, redirect, url_for, render_template, request, jsonify, current_app, abort

from info import db
from info.constants import USER_COLLECTION_MAX_NEWS, QINIU_DOMIN_PREFIX, USER_FOLLOWED_MAX_COUNT
from info.models import UserCollection, Category, News, User
from info.modules.user import user_blu
from info.utils.common import user_login_data, file_upload
from info.utils.response_code import RET, error_map


@user_blu.route("/user_info")
@user_login_data
def user_info():
    user = g.user
    if not user:
        return redirect(url_for("home.index"))

    return render_template("news/user.html", user=user.to_dict())


# 基本资料界面
@user_blu.route("/base_info", methods=["GET", "POST"])
@user_login_data
def base_info():
    user = g.user
    if not user:  # 未登录, 跳转到首页
        return abort(403)

    # GET请求,展示界面
    if request.method == "GET":
        return render_template("news/user_base_info.html", user=user.to_dict())

    # POST请求,提交资料
    # 获取和校验参数
    signature = request.json.get("signature")
    nick_name = request.json.get("nick_name")
    gender = request.json.get("gender")
    if not all([signature, nick_name, gender]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    if gender not in ["MAN", "WOMAN"]:
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 修改用户资料
    user.signature = signature
    user.nick_name = nick_name
    user.gender = gender

    # json返回
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 展示和修改界面
@user_blu.route("/pic_info", methods=["POST", "GET"])
@user_login_data
def pic_info():
    user = g.user
    if not user:  # 未登录,重定向到首页
        return redirect(url_for("home.index"))

    # GET请求
    if request.method == "GET":
        return render_template("news/user_pic_info.html", user=user.to_dict())

    # POST请求
    avatar_file = request.files.get("avatar")
    try:
        avatar_bytes = avatar_file.read()  # 读取出文件中的二进制数据
        # 一般开发中会将静态文件单独进行管理(使用文件服务器),此处将数据保存到七牛云服务器
        try:
            file_name = file_upload(avatar_bytes)
        except BaseException as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.THIRDERR, errmsg=error_map[RET.THIRDERR])

        # 修改用户头像的url
        user.avatar_url = file_name

    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK], data=user.to_dict())


@user_blu.route("/pass_info", methods=["GET", "POST"])
@user_login_data
def pass_info():
    user = g.user
    if not user:  # 未登录,重定向到首页
        return redirect(url_for("home.index"))

    # GET请求
    if request.method == "GET":
        return current_app.send_static_file("news/html/user_pass.info.html", user=user.to_dict())

    # POST请求, 提交资料
    # 获取和校验参数
    old_password = request.json.get("old_password")
    new_password = request.json.get("new_password")

    if not all([new_password, old_password]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 校验旧密码
    if not user.check_password(old_password):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 修改新密码
    user.password = new_password

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 　新闻收藏界面
@user_blu.route("/collection")
@user_login_data
def collection():
    user = g.user
    if not user:  # 未登录,重定向到首页
        return redirect(url_for("home.index"))

    # 获取和校验参数
    p = request.args.get("p", 1)
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(403)

    # 查询用户收藏的所有信息，根据收藏顺序倒序
    try:
        pn = user.collection_news.order_by(UserCollection.create_time.desc()).paginate(p, USER_COLLECTION_MAX_NEWS)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(500)

    data = {
        "news_list": [news.to_dict() for news in pn.items],
        "total_page": pn.pages,
        "cur_page": pn.page
    }

    # 传入模板渲染
    return render_template("news/user_collection.html", data=data)


# 新闻发布
@user_blu.route("/news_release", methods=["GET", "POST"])
@user_login_data
def news_release():
    user = g.user
    if not user:  # 未登录,重定向到首页
        return abort(403)

    # GET请求
    if request.method == "GET":
        try:
            categories = Category.query.filter(Category.id != 1).all()
        except BaseException as e:
            current_app.logger.error(e)
            return abort(500)

        # 传入模板渲染
        return render_template("news/user_news_release.html", categories=categories)

    # POST请求
    title = request.form.get("title")
    category_id = request.form.get("category_id")
    digest = request.form.get("digest")
    content = request.form.get("content")
    img_file = request.files.get("index_image")
    if not all([title, category_id, digest, content, img_file]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 生成一条新闻记录
    news = News()
    news.title = title
    news.category_id = category_id
    news.digest = digest
    news.content = content
    # 上传图片
    try:
        img_bytes = img_file.read()
        file_name = file_upload(img_bytes)
        # 记录图片URL
        news.index_image_url = QINIU_DOMIN_PREFIX + file_name
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg=error_map[RET.THIRDERR])

    news.user_id = user.id  # 设置作者的id
    news.source = "个人发布"
    news.status = 1  # 待审核状态

    # 添加到数据库
    db.session.add(news)

    # 返回json
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 　我的发布列表
@user_blu.route("/news_list")
@user_login_data
def news_list():
    user = g.user
    if not user:  # 未登录, 重定向到首页
        return abort(403)

    # 获取和校验参数
    p = request.args.get("p", 1)
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 查询数据库数据
    try:
        pn = user.news_list.order_by(News.create_time.desc()).paginate(p, USER_COLLECTION_MAX_NEWS)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg=error_map[RET.DBERR])

    data = {
        "news_list": [news.to_review_dict() for news in pn.items],
        "total_page": pn.pages,
        "cur_page": pn.page
    }
    return render_template("news/user_news_list.html", data=data)


@user_blu.route("/user_follow")
@user_login_data
def user_follow():
    user = g.user
    if not user:
        return abort(403)

    # 获取和校验参数
    p = request.args.get("p", 1)
    try:
        p = int(p)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(403)

    # 查询用户关注的所有作者 根据页码
    try:
        pn = user.followed.paginate(p,USER_FOLLOWED_MAX_COUNT)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(500)

    data={
        "author_list":[author.to_dict() for author in pn.items],
        "total_page":pn.pages,
        "cur_page":pn.page
    }

    # 传入模板
    return render_template("news/user_follow.html",data=data)